package com.lfy.chat.client;

import cn.hutool.core.util.StrUtil;
import com.lfy.common.constant.GlobalConstant;
import io.netty.channel.Channel;
import io.netty.util.AttributeKey;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 状态管理
 *
 * @author <a href="https://www.lvfeiy.top">吕飞扬</a>
 * @date 2023/10/24 11:23
 */
@Slf4j
public class ChannelCache {
    public static Map<String, Channel> WS_CHANNEL = new ConcurrentHashMap<>();
    public static AttributeKey<String> USER = AttributeKey.newInstance("user");

    public static Map<String, CopyOnWriteArrayList<Channel>> WS_GROUP_CHAT = new ConcurrentHashMap<>();

    public static void bind(String id,Channel channel){
        WS_CHANNEL.put(id,channel);
        channel.attr(USER).set(id);
    }
    public static void unBinding(Channel channel){
        if(Objects.isNull(channel)){
            return;
        }
        String id = channel.attr(USER).get();
        if(StrUtil.isBlank(id)){
            log.error("WS :unBinding error channel no bind userId :{}",id );
            return;
        }
        WS_CHANNEL.remove(id);

    }
    public static Channel getChannel(String id){

        return WS_CHANNEL.get(id);
    }
    public static String getId(Channel channel){
        return channel.attr(USER).get();
    }

    /**
     * 群
     * @param groupId 群id
     * @return 布尔
     */
    public static boolean groupContainsKey(String groupId){
        if(StrUtil.isBlank(groupId)){
            return false;
        }
        return WS_GROUP_CHAT.containsKey(groupId);
    }

    public static  void bindGroup(String groupId,Channel channel){
        synchronized((GlobalConstant.CHANNEL_LOCK_PREFIX.concat(groupId)).intern()){
            if(!groupContainsKey(groupId)){
                CopyOnWriteArrayList<Channel> list = new CopyOnWriteArrayList<>();
                list.add(channel);
                WS_GROUP_CHAT.put(groupId,list);
            }else {
                WS_GROUP_CHAT.get(groupId).add(channel);
            }
        }


    }
    public static void unBindGroup(String groupId, Channel channel){
        if(StrUtil.isBlank(groupId) || Objects.isNull(channel)){
            log.error("WS: unBindGroup params error");
            return;
        }
        synchronized((GlobalConstant.CHANNEL_LOCK_PREFIX.concat(groupId)).intern()){
            CopyOnWriteArrayList<Channel> channels = WS_GROUP_CHAT.get(groupId);
            channels.remove(channel);
            if(channels.size() == GlobalConstant.I_0){
                WS_GROUP_CHAT.remove(groupId);
            }
        }

    }


}
